import { onUnmounted } from 'vue'
import { MediaPlayer } from './mediaPlayer'
import type { MediaView } from '@/api/children.typing'

export class BackgroundAudioPlayer extends MediaPlayer {
  // 音频特定状态
  audioContext = ref<UniApp.BackgroundAudioManager | null>(null)
  sliderValue = ref(0)
  expiredMediaIds = ref<Set<number>>(new Set())
  nextTrackCallback: (() => void) | null = null
  saveProgress = ref<boolean>(true)

  constructor(saveProgress: boolean = true) {
    super()
    this.saveProgress.value = saveProgress
    console.log(' this.saveProgress.value:', this.saveProgress.value)
    onUnmounted(() => this.stop())
  }

  // 初始化音频上下文
  private initAudioContext() {
    if (!this.audioContext.value) {
      this.audioContext.value = uni.getBackgroundAudioManager()

      // 绑定事件监听器
      this.audioContext.value.onEnded(() => this.handleEnded())
      this.audioContext.value.onError((err) => this.handleError(err))
      this.audioContext.value.onPlay(() => this.handlePlay())
      this.audioContext.value.onPause(() => this.handlePause())
      this.audioContext.value.onTimeUpdate(() => this.handleTimeUpdate())
    }
    return this.audioContext.value
  }

  // 事件处理函数
  private handleEnded() {
    this.isPlaying.value = false
    if (this.playingItem.value && this.saveProgress.value) {
      console.log('handleEnd savePlaybackProgress')
      this.savePlaybackProgress(this.playingItem.value.id, this.duration.value)
    }
    this.nextTrackCallback?.()
  }

  private handleError(err: any) {
    console.error(`播放失败: ${err.errMsg}`)
    this.isPlaying.value = false
  }

  private handlePlay() {
    this.isPlaying.value = true
  }

  private handlePause() {
    this.isPlaying.value = false
    if (this.playingItem.value && this.audioContext.value && this.saveProgress.value) {
      console.log('handlePause savePlaybackProgress')

      this.savePlaybackProgress(this.playingItem.value.id, this.audioContext.value.currentTime)
    }
  }

  private handleTimeUpdate() {
    if (!this.audioContext.value) return

    this.sliderValue.value = this.audioContext.value.currentTime
    this.currentTime.value = this.audioContext.value.currentTime
    // console.log('[backgroundAudioPlayer] sliderValue 变化为:', this.sliderValue.value)

    const now = Date.now()
    if (
      now - this.lastSaveTime > this.SAVE_INTERVAL &&
      this.playingItem.value &&
      this.saveProgress.value
    ) {
      console.log('handleTimeUpdate savePlaybackProgress')
      this.savePlaybackProgress(this.playingItem.value.id, this.audioContext.value.currentTime)
      this.lastSaveTime = now
    }
  }

  // 实现抽象方法
  play(item: MediaView, progressSeconds: number = 0) {
    this.playingItem.value = item
    this.isPlaying.value = true
    this.duration.value = item.duration
    this.sliderValue.value = progressSeconds
    const ctx = this.initAudioContext()
    ctx.title = item.title || '梦瑶诗歌'
    ctx.epname = '儿童专辑'
    ctx.src = item.filePath
    ctx.seek(progressSeconds)
    ctx.play()
  }

  pause() {
    if (this.audioContext.value && this.isPlaying.value) {
      this.audioContext.value.pause()
    }
  }

  resume() {
    if (this.audioContext.value && !this.isPlaying.value) {
      this.audioContext.value.play()
    }
  }

  stop() {
    if (this.audioContext.value) {
      if (this.playingItem.value && this.saveProgress.value) {
        this.savePlaybackProgress(this.playingItem.value.id, this.audioContext.value.currentTime)
      }
      this.audioContext.value.pause()
      this.audioContext.value.stop()
      this.audioContext.value = null
    }
    this.playingItem.value = null
    this.isPlaying.value = false
    this.sliderValue.value = 0
  }

  // 音频特定方法
  toggle(item: MediaView, progressSeconds: number = 0) {
    if (this.playingItem.value?.id !== item.id) {
      // console.log('音频id不一致，先关闭旧音频再开始新的音频')
      this.stop()
      this.play(item, progressSeconds)
      return
    }

    this.isPlaying.value ? this.pause() : this.resume()
  }

  setNextTrackCallback(callback: () => void) {
    this.nextTrackCallback = callback
  }

  // 检查媒体过期状态
  checkMediaExpiration(item: MediaView) {
    if (this.expiredMediaIds.value.has(item.id)) return true

    const now = Date.now()
    if (item.expirationDate && now > item.expirationDate) {
      this.expiredMediaIds.value.add(item.id)
      return true
    }

    return false
  }
}
